package cn.iocoder.yudao.module.reading.service.community;

import cn.iocoder.yudao.module.reading.controller.app.community.vo.report.ReportCreateReqVO;
import cn.iocoder.yudao.module.reading.dal.dataobject.community.CommunityReportDO;
import cn.iocoder.yudao.module.reading.util.CommunityValidationUtils;
import cn.iocoder.yudao.module.reading.dal.mysql.community.CommunityCommentMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.community.CommunityPostMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.community.CommunityReportMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.reading.enums.ErrorCodeConstants.*;

/**
 * 社区举报服务实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class CommunityReportServiceImpl implements CommunityReportService {

    @Resource
    private CommunityReportMapper reportMapper;

    @Resource(name = "communityPostMapper")
    private CommunityPostMapper postMapper;

    @Resource
    private CommunityCommentMapper commentMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createReport(ReportCreateReqVO createReqVO, Long reporterId) {
        // 1. 参数校验
        CommunityValidationUtils.validateId(createReqVO.getTargetId(), "举报目标ID");
        CommunityValidationUtils.validateReportReason(createReqVO.getReason());

        // 2. 校验举报目标存在
        validateTargetExists(createReqVO.getTargetType(), createReqVO.getTargetId());

        // 2. 检查是否已经举报过
        CommunityReportDO existingReport = reportMapper.selectByReporterAndTarget(
                reporterId, createReqVO.getTargetType(), createReqVO.getTargetId());
        if (existingReport != null) {
            log.info("[createReport][用户已举报过该内容] reporterId: {}, targetType: {}, targetId: {}", 
                    reporterId, createReqVO.getTargetType(), createReqVO.getTargetId());
            return existingReport.getId(); // 返回已有举报记录的ID
        }

        // 3. 创建举报记录
        CommunityReportDO report = CommunityReportDO.builder()
                .reporterId(reporterId)
                .targetType(createReqVO.getTargetType())
                .targetId(createReqVO.getTargetId())
                .reason(createReqVO.getReason())
                .status(0) // 待处理
                .build();
        reportMapper.insert(report);

        log.info("[createReport][举报创建成功] reportId: {}, reporterId: {}, targetType: {}, targetId: {}", 
                report.getId(), reporterId, createReqVO.getTargetType(), createReqVO.getTargetId());

        return report.getId();
    }

    /**
     * 校验举报目标是否存在
     */
    private void validateTargetExists(String targetType, Long targetId) {
        switch (targetType) {
            case "post":
                if (postMapper.selectById(targetId) == null) {
                    throw exception(COMMUNITY_POST_NOT_EXISTS);
                }
                break;
            case "comment":
                if (commentMapper.selectById(targetId) == null) {
                    throw exception(COMMUNITY_COMMENT_NOT_EXISTS);
                }
                break;
            default:
                throw new IllegalArgumentException("不支持的举报目标类型: " + targetType);
        }
    }

}
